import java.io.*;
import java.util.*;

public class ScoreManager {
    private List<Student> students = new ArrayList<>();
    private List<Course> courses = new ArrayList<>();
    private List<Score> scores = new ArrayList<>();
    private final String DATA_FILE = "score_data.ser";
    private Scanner scanner = new Scanner(System.in);

    // 原有核心方法（添加学生、课程、成绩，计算GPA，查询成绩，保存/加载数据）不变
    public void addStudent(Student student) { students.add(student); }
    public void addCourse(Course course) { courses.add(course); }
    public void addScore(Score score) { scores.add(score); }

    public double calculateGPA(Student student) {
        double totalGradePoints = 0;
        double totalCredits = 0;
        for (Score score : scores) {
            if (score.getStudent().getId().equals(student.getId())) {
                Course course = score.getCourse();
                totalGradePoints += score.getGradePoint() * course.getCredit();
                totalCredits += course.getCredit();
            }
        }
        return totalCredits == 0 ? 0 : totalGradePoints / totalCredits;
    }

    public Double queryCourseScore(Student student, Course course) {
        for (Score score : scores) {
            if (score.getStudent().getId().equals(student.getId())
                    && score.getCourse().getCourseId().equals(course.getCourseId())) {
                return score.getScore();
            }
        }
        return null;
    }

    public void saveToFile() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DATA_FILE))) {
            oos.writeObject(students);
            oos.writeObject(courses);
            oos.writeObject(scores);
            System.out.println("数据已保存至 " + DATA_FILE);
        } catch (IOException e) {
            System.err.println("保存数据失败：" + e.getMessage());
        }
    }

    @SuppressWarnings("unchecked")
    public void loadFromFile() {
        File file = new File(DATA_FILE);
        if (!file.exists()) {
            System.out.println("数据文件不存在，将创建新数据！");
            return;
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(DATA_FILE))) {
            students = (List<Student>) ois.readObject();
            courses = (List<Course>) ois.readObject();
            scores = (List<Score>) ois.readObject();
            System.out.println("数据已从 " + DATA_FILE + " 加载完成！");
        } catch (IOException | ClassNotFoundException e) {
            System.err.println("加载数据失败：" + e.getMessage());
        }
    }

    // ========== 新增手动交互功能 ==========
    // 显示功能菜单
    public void showMenu() {
        System.out.println("\n===== 学生成绩管理系统 =====");
        System.out.println("1. 加载历史数据");
        System.out.println("2. 添加学生");
        System.out.println("3. 添加课程");
        System.out.println("4. 添加成绩（自动校验分数范围）");
        System.out.println("5. 手动查询某课程成绩");
        System.out.println("6. 手动查询学生GPA");
        System.out.println("7. 保存数据");
        System.out.println("0. 退出系统");
        System.out.print("请选择功能序号：");
    }

    // 处理用户输入
    public void handleUserInput() {
        int choice;
        do {
            showMenu();
            choice = scanner.nextInt();
            scanner.nextLine(); // 清空输入缓冲区
            switch (choice) {
                case 1:
                    loadFromFile();
                    break;
                case 2:
                    addStudentManually();
                    break;
                case 3:
                    addCourseManually();
                    break;
                case 4:
                    addScoreManually();
                    break;
                case 5:
                    queryCourseScoreManually();
                    break;
                case 6:
                    queryStudentGPAManually();
                    break;
                case 7:
                    saveToFile();
                    break;
                case 0:
                    System.out.println("退出系统成功！");
                    break;
                default:
                    System.out.println("输入错误，请重新选择！");
            }
        } while (choice != 0);
        scanner.close();
    }

    // 手动添加学生
    private void addStudentManually() {
        System.out.print("请输入学号：");
        String id = scanner.nextLine();
        System.out.print("请输入姓名：");
        String name = scanner.nextLine();
        System.out.print("请输入班级：");
        String className = scanner.nextLine();
        addStudent(new Student(id, name, className));
        System.out.println("学生添加成功！");
    }

    // 手动添加课程
    private void addCourseManually() {
        System.out.print("请输入课程编号：");
        String courseId = scanner.nextLine();
        System.out.print("请输入课程名称：");
        String courseName = scanner.nextLine();
        System.out.print("请输入学分：");
        double credit = scanner.nextDouble();
        addCourse(new Course(courseId, courseName, credit));
        System.out.println("课程添加成功！");
    }

    // 手动添加成绩（显示分数范围异常）
    private void addScoreManually() {
        System.out.print("请输入学生学号：");
        String studentId = scanner.nextLine();
        System.out.print("请输入课程编号：");
        String courseId = scanner.nextLine();
        System.out.print("请输入分数：");
        double score = scanner.nextDouble();

        // 查找学生和课程
        Student targetStudent = students.stream()
                .filter(s -> s.getId().equals(studentId))
                .findFirst().orElse(null);
        Course targetCourse = courses.stream()
                .filter(c -> c.getCourseId().equals(courseId))
                .findFirst().orElse(null);

        if (targetStudent == null) {
            System.out.println("未找到该学号的学生！");
            return;
        }
        if (targetCourse == null) {
            System.out.println("未找到该编号的课程！");
            return;
        }

        // 添加成绩并捕获分数异常
        try {
            addScore(new Score(targetStudent, targetCourse, score));
            System.out.println("成绩添加成功！");
        } catch (ScoreException e) {
            System.err.println("❌ 分数范围异常：" + e.getMessage());
        }
    }

    // 手动查询某课程成绩
    private void queryCourseScoreManually() {
        System.out.print("请输入学生学号：");
        String studentId = scanner.nextLine();
        System.out.print("请输入课程编号：");
        String courseId = scanner.nextLine();

        Student targetStudent = students.stream()
                .filter(s -> s.getId().equals(studentId))
                .findFirst().orElse(null);
        Course targetCourse = courses.stream()
                .filter(c -> c.getCourseId().equals(courseId))
                .findFirst().orElse(null);

        if (targetStudent == null) {
            System.out.println("未找到该学号的学生！");
            return;
        }
        if (targetCourse == null) {
            System.out.println("未找到该编号的课程！");
            return;
        }

        Double score = queryCourseScore(targetStudent, targetCourse);
        if (score != null) {
            System.out.printf("%s的《%s》成绩为：%.1f%n",
                    targetStudent.getName(), targetCourse.getCourseName(), score);
        } else {
            System.out.println("未查询到该学生的此课程成绩！");
        }
    }

    // 手动查询学生GPA
    private void queryStudentGPAManually() {
        System.out.print("请输入学生学号：");
        String studentId = scanner.nextLine();

        Student targetStudent = students.stream()
                .filter(s -> s.getId().equals(studentId))
                .findFirst().orElse(null);

        if (targetStudent == null) {
            System.out.println("未找到该学号的学生！");
            return;
        }

        double gpa = calculateGPA(targetStudent);
        System.out.printf("%s的GPA为：%.2f%n", targetStudent.getName(), gpa);
    }

    // 主方法：启动手动交互模式
    public static void main(String[] args) {
        ScoreManager manager = new ScoreManager();
        manager.handleUserInput();
    }
}